fix: improve overlapping events with dynamic offsets and widths#25310
Merged
sean-brydon merged 13 commits intomainfrom Nov 24, 2025
Merged
fix: improve overlapping events with dynamic offsets and widths#25310sean-brydon merged 13 commits intomainfrom
sean-brydon merged 13 commits intomainfrom
Conversation
- Implement dynamic offset calculation based on number of overlapping events - 2 events: 15% offset (larger for better visual distinction) - 3 events: 10% offset (medium) - 4 events: 8% offset (base) - 5+ events: progressively smaller offsets to prevent overflow - Implement dynamic width reduction for better visual distinction - 2 events: 75% width - 3 events: 70% width - 4 events: 65% width - 5+ events: progressively narrower (min 50%) - Update playground scenarios to showcase the new behavior - Updated expected descriptions for 2, 3, and 4 event scenarios - Added new scenario specifically for 4 overlapping events This makes overlapping events more visually distinguishable, with larger offsets and narrower widths for fewer events, and tighter packing for many events to prevent overflow. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
- Fix implementation to honor explicitly provided baseWidthPercent and offsetStepPercent - Only apply dynamic calculations when config values are not explicitly set - Update test expectations to reflect new dynamic behavior: - 2 events: 15% offset, 75% width (was 8% offset, 80% width) - 3 events: 10% offset, 70% width (was 8% offset, 80% width) - Rename test to better reflect dynamic width behavior - All 21 tests now pass Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
- Replace uniform widths with variable widths based on cascade position - Leftmost (longest) events get wider widths, rightmost (shortest) get narrower - Anchor points: 2 events (80%, 50%), 3 events (55%, ~42%, 33%), 4 events (40%, ~33%, ~28%, 25%) - Use easing curve (exponent 1.3) for smooth width distribution in 5+ events - Maintain minimum width of 25% for readability - Update offset calculation to work with variable widths - Update tests to reflect new variable width behavior - Update playground scenarios to document new behavior Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
…gned to right - Replace fixed-step offsets with linear right edges distribution - Events now spread across full width instead of clustering on left - Last event aligns to right border (100% - safety margin) - Right edges evenly distributed: ri = Rmin + (Rmax - Rmin) * i/(n-1) - Maintains backward compatibility: explicit offsetStepPercent uses legacy behavior - Update tests to reflect new offset values (e.g., 2 events: 0%, 49.5%) - Update playground descriptions to document spread behavior Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
- Update CurrentTime component to accept scrollToCurrentTime prop (default: true) - Pass scrollToCurrentTime from Calendar.tsx to CurrentTime component - Set scrollToCurrentTime to false in playground to disable auto-scroll - Maintains backward compatibility with default value of true Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
…ts 100% width - Update calculateVariableWidths to return 100% width for single events (was 80%) - Add startHour parameter to getBaseProps function in playground - Set appropriate startHour for each scenario based on earliest event time: - Most scenarios: startHour 9 (events start at 10:00) - Dense day & event durations: startHour 8 (events start at 9:00) - Mixed statuses: startHour 13 (events start at 14:00) - Update expected descriptions for non-overlapping events to reflect 100% width - Update test expectations for single event width (99.5% after safety margin) Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
- Import Hours type from weeklyview/types/state - Change startHour parameter type from number to Hours in getBaseProps - Change Scenario.startHour type from number to Hours - Fixes type error: Type 'number' is not assignable to type 'Hours | undefined' Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
- Remove safety margin cap for single-event groups (allow true 100% width) - Keep safety margin for overlapping groups to prevent overflow - Update test expectations from 99.5% to 100% for single events - Add test for touching events at exact boundaries with 100% width - Fixes issue where touching events were displaying at 99.5% instead of 100% Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
sean-brydon
approved these changes
Nov 24, 2025
Contributor
E2E results are ready! |
Member
Merge activity
|
This was referenced Dec 4, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Improves the visual presentation of overlapping calendar events in the weekly view with two key enhancements:
on its earliest event time, rather than always starting at 6am
80%) for maximum visibility
Key Changes
Overlapping Event Layout Algorithm
Replaces the previous uniform-width, fixed-offset layout with an intelligent spread algorithm:
Previous behavior:
New behavior:
ri = Rmin + (Rmax - Rmin) × i/(n-1)for even spacingVisual Improvements
Devin session: https://app.devin.ai/sessions/168d2227f5304c49ae4d34d17da5b025
Requested by: eunjae@cal.com (@eunjae-lee)
Visual Demo
Screenshot.2025-11-24.at.10.30.55.mp4
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
/settings/admin/playground/weekly-calendarEnvironment variables: Standard Cal.com development setup
Test data: Use playground scenarios or create overlapping events in your calendar
Human Review Checklist
Visual verification in playground (MOST IMPORTANT):
/settings/admin/playground/weekly-calendarAlgorithm correctness:
ri = Rmin + (Rmax - Rmin) * i/(n-1)Edge cases:
baseWidthPercent/offsetStepPercentshould use legacy behaviorType safety:
startHourparameter now properly typed asHours(union of 0-23)HoursvaluesKnown limitations:
Checklist